package seqAlignment;

import java.awt.Point;

import seqAlignment.utils.MatrixOut;

public class AffineGPLAlingerAllPaths extends AffineGPLocalAligner {
	
	Point[][][] allPathM;
	Point[][][] allPathX;
	Point[][][] allPathY;
	
	public void init() {
		super.init();
		allPathM=new AffineGPPoint[str1.length()+1][str2.length()+1][3];
		allPathX=new AffineGPPoint[str1.length()+1][str2.length()+1][3];
		allPathY=new AffineGPPoint[str1.length()+1][str2.length()+1][3];
	}
	protected void getLocalPath(int x, int y) {
		super.getLocalPath(x, y);
		
		//populate M
		int xM = add(matrixX[x-1][y-1],scoreFunction.score(matrix, x, y));
		int yM= add(matrixY[x-1][y-1],scoreFunction.score(matrix, x, y));
		int mM = add(matrix[x-1][y-1],scoreFunction.score(matrix, x, y));
		int max = Math.max( Math.max(xM,yM), mM);
		max = Math.max(max, 0);

	//higher
		if (max==xM) {
			allPathM[x][y][0]= new AffineGPPoint(pathX,x-1,y-1);
		} 
		if (max==mM) {
			allPathM[x][y][1] = new AffineGPPoint(path,x-1,y-1);
		}
		if (max==yM){
			allPathM[x][y][2] = new AffineGPPoint(pathY,x-1,y-1);
		}		
		
		//populate X
		int mX=add(matrix[x-1][y],penaltyFunction.headPenalty(x-1,y)+penaltyFunction.gapPenalty(x-1,y));
		int xX=add(matrixX[x-1][y],penaltyFunction.gapPenalty(x-1,y));
		if (xX>=mX) {
			allPathX[x][y][0]=new AffineGPPoint(pathX,x-1,y);
		}
		if (mX>=xX) {
			allPathX[x][y][1]=new AffineGPPoint(path,x-1,y);
		}
		
		//populate y
		int mY=add(matrix[x][y-1],penaltyFunction.headPenalty(x,y-1)+penaltyFunction.gapPenalty(x,y-1));
		int yY=add(matrixY[x][y-1],penaltyFunction.gapPenalty(x,y-1));
		if (mY>=yY) {
			allPathY[x][y][0]=new AffineGPPoint(path,x,y-1);
		}
		if (yY>=mY) {
			allPathY[x][y][1]=new AffineGPPoint(pathY,x,y-1);
		}
	}
	
	public void align() {
		super.align();
		MatrixOut.out(allPathM, allPathX, allPathY, path,pathX, pathY);
	}

}
